package com.societyGames.codeAlong.codeExercise
{
import com.codeazur.as3swf.SWF;
import com.codeazur.as3swf.SWFData;
import com.codeazur.as3swf.tags.TagDoABC;
import com.codeazur.as3swf.tags.TagEnd;
import com.codeazur.as3swf.tags.TagFileAttributes;
import com.codeazur.as3swf.tags.TagShowFrame;
import com.societyGames.system.EventObject;

import flash.events.Event;
import flash.events.EventDispatcher;
import flash.utils.ByteArray;

public class Compiler extends EventDispatcher
{
  private static var _instance:Compiler = new Compiler();
  private var _isInitialized:Boolean = false;
  private var _initializedEventObject:EventObject;

  public function Compiler()
  {
    this._initializedEventObject = new EventObject(this, "INITIALIZED");
  }

  public static function get instance():Compiler
  {
    return Compiler._instance;
  }

  public function get initializedEventObject():EventObject
  {
    return this._initializedEventObject;
  }

  public function initialize():void
  {
    if (this._isInitialized)
    {
      this._initializedEventObject.dispatchEvent();
    }
    else
    {
      CompiledESC.instance.addEventListener(CompiledESC.INITIALIZED, compilerInitializedHandler);
      CompiledESC.instance.initialize();
    }
  }

  private function compilerInitializedHandler(event:Event):void
  {
    CompiledESC.instance.removeEventListener(CompiledESC.INITIALIZED, compilerInitializedHandler);
    this._isInitialized = true;
    this._initializedEventObject.dispatchEvent();
  }

  //Throws SyntaxError on syntax error
  public function compileSwf(text:String, identifier:String):ByteArray
  {
    if (!this._isInitialized)
    {
      throw new Error("Compiler instance not initialized.");
    }
    //Create a SWF to hold the compiled abc code.
    var swf:SWF = new SWF();
    swf.version = 9;
    swf.frameSize.xmax = 4000;
    swf.frameSize.ymax = 4000;
    swf.frameRate = 30;
    swf.compressed = false;
    swf.tags.push(new TagFileAttributes());
    //swf.tags.push(new TagEnableDebugger2());

    //Create the ABC code
    var abcByteArray:ByteArray = CompiledESC.instance.eval(text, identifier);
    swf.tags.push(TagDoABC.create(abcByteArray, '', false));

    swf.tags.push(new TagShowFrame());
    swf.tags.push(new TagEnd());

    var swfData:SWFData = new SWFData();
    //Generate byte array representing the SWF
    swf.publish(swfData);

    //Return it.
    return swfData;
  }
}
}